#pragma once
#include "Socket.hpp"
#include <memory>
#include <functional>
#include <unistd.h>
#include <sys/wait.h>
#include "InetAddr.hpp"
#include "Common.hpp"
#include "Log.hpp"

using namespace LogModule;
using namespace SocketModule;

// 只做通信
class TcpServer
{
    using func_t = std::function<void(std::shared_ptr<Socket>, const InetAddr &)>;

public:
    TcpServer(const InetAddr &addr, func_t func)
        : _sock(std::make_unique<TCPSocket>(addr, Type::SERVER)), _isrunning(false), _func(func)
    {
    }
    void Start()
    {
        _isrunning = true;
        while (_isrunning)
        {
            // 1.获取连接
            InetAddr addr;
            auto sock = _sock->Accept(&addr);
            if (sock == nullptr)
            {
                LOG(LogLevel::WARNING) << "accept error";
                continue;
            }
            // 多进程版本
            pid_t pid = fork();
            if (pid < 0)
            {
                LOG(LogLevel::FATAL) << "fork error";
                exit(FORK_ERR);
            }
            else if (pid == 0)
            {
                // 监听的_sock关闭
                _sock->Close();
                if (fork() > 0)
                    exit(OK);
                // 孙子进程执行业务
                _func(sock, addr);
                sock->Close();
                exit(OK);
            }
            else
            {
                // 父进程的通信sock关闭
                sock->Close();
                waitpid(pid, nullptr, 0);
            }
        }
        _isrunning = false;
    }

    ~TcpServer()
    {
    }

private:
    std::unique_ptr<TCPSocket> _sock;
    bool _isrunning;
    func_t _func;
};